home *** CD-ROM | disk | FTP | other *** search
- program Julia;
-
- { This program generates a section of the Julia Set, can save it on
- disk and use existing Julia pictures to zoom further into the set }
-
-
- {$IFDEF CPU87} {$N+} {$ELSE} {$N-} {$ENDIF}
- uses
- Crt, Graph, General, IO_Sup, PopUps,
- Cmplx, mouse;
-
-
- {$IFOPT N-}
- TYPE
- double = real;
- {$ENDIF}
-
- const
- Scan_width = 359; { 719 (max Hercules) div 2 }
- Max_Scan_Lines = 349; { PC 3270 max }
- Aspect = 0.75;
- Real_Length = 30;
- Yes_N_No : Set of Char = ['Y','N','y','n'];
- Yes : set of char = ['Y','y'];
- No : set of char = ['N','n'];
- DriverPath : string = 'c:\prgm';
- Mouse_Flag : boolean = false;
- ResStrArray : array[0..2] of String[10] =
- ('CGAHighRes','EGALowRes','EGAHighRes');
-
- MainMenu : menuRec =
- (row : 1;
- interval : 24;
- fore : white;
- back : green);
- MainMenuText : String[23] = 'Create~File~Config~Exit';
- MemWindo : popRec =
- (Left : 5;
- Top : 5;
- Right : 75;
- Bottom : 20;
- Style : 1;
- Normal : LightCyan;
- Hilite : LightGray;
- NormBack : Black;
- HiBack : Magenta;
- Border : Red);
- OpenWindo : popRec =
- (Left : 1;
- Top : 1;
- Right : 80;
- Bottom : 25;
- Style : 1;
- Normal : Green;
- Hilite : LightGray;
- NormBack : Black;
- HiBack : Magenta;
- Border : Yellow);
- MouseWindo : popRec =
- (Left : 5;
- Top : 5;
- Right : 75;
- Bottom : 15;
- Style : 1;
- Normal : Green;
- Hilite : LightGray;
- NormBack : Black;
- HiBack : Magenta;
- Border : Yellow);
- GrafWindo : popRec =
- (Left : 5;
- Top : 5;
- Right : 75;
- Bottom : 20;
- Style : 1;
- Normal : Yellow;
- Hilite : LightGray;
- NormBack : Black;
- HiBack : Magenta;
- Border : Green);
- ResWindo : popRec =
- (Left : 5;
- Top : 5;
- Right : 75;
- Bottom : 20;
- Style : 1;
- Normal : Yellow;
- Hilite : LightGray;
- NormBack : Black;
- HiBack : Magenta;
- Border : Green);
-
- type
- ResType = (CGAHighRes,EGALowRes,EGAHighRes);
- Real_String = String[Real_Length];
- Color_Array = Array[0..55] of integer;
- ScreenArray = Array[1..1] of byte;
- ScrnDataRec = Record
- Dots_H, Dots_V, Count, Start : integer;
- Con_Real, Con_Imag,
- Low_Real, Low_Imag,
- High_Real, High_Imag : Real_String;
- ScrnSize : word;
- ResStr : String[10];
- Note : String[80];
- end;
-
- const
- Colors_2 : Color_Array = (0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1,
- { Color arrangement } 0, 0, 0, 0, 1, 1, 1, 1,
- { for 2 color screens } 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1);
-
- Colors_4 : Color_Array = (1, 2, 1, 2, 1, 2, 3, 2, 3, 2, 3, 2,
- 1, 3, 1, 3, 1, 3, 2, 1, 2, 1, 2, 1,
- { Color arrangement } 3, 2, 3, 2, 3, 2, 1, 3, 1, 3, 1, 3,
- { for 4 color screens } 2, 1, 2, 1, 2, 1, 3, 2, 3, 2, 3, 2,
- 1, 3, 1, 3, 1, 3, 0, 0);
-
- Colors_16 : Color_Array = (1, 9, 1, 9, 1, 9, 1, 9,
- 2, 10, 2, 10, 2, 10, 2, 10,
- 3, 11, 3, 11, 3, 11, 3, 11,
- 4, 12, 4, 12, 4, 12, 4, 12,
- 5, 13, 5, 13, 5, 13, 5, 13,
- 6, 14, 6, 14, 6, 14, 6, 14,
- 7, 15, 7, 15, 7, 15, 7, 15);
-
- XMul : integer = 1; { These constants determine the size of }
- XDiv : integer = 1; { the Text displayed at the bottom of }
- YMul : integer = 1; { the Graphics screen giving the limits of }
- YDiv : integer = 1; { the area being created }
-
- var
- Resolution : ResType;
- ch : char;
- Low, High,
- Con, Delta : Complex;
- IOError,
- Dots_Horizontal,
- Dots_Vertical,
- Start_Y, Max_Count,
- Color_Count,
- Driver, Graph_Mode,
- Max_Colors,
- Max_X, Max_Y : integer;
- Use_Color : Color_Array;
- Stop,
- Picture_Loaded : boolean;
- Maus : Mouse_Event;
- HCursor,
- VCursor : pointer;
- LowReal, LowImag,
- HighReal, HighImag : String[15];
- File_Name : String[80];
- LimitStr : string;
- Screen_Data : ScrnDataRec;
- Data_File : File of ScrnDataRec;
- Screen_File : File;
- ScreenSize : word;
- Scrn1,
- Scrn2 : ^ScreenArray;
-
- procedure MemError(ErrCode : integer);
- begin
- RestoreCRTMode;
- PopShow(MemWindo);
- if Center('There is not enough heap memory to load the Screen Into',True) then;
- if Center('This could be due to too many TSR''s being loaded or an',True) then ;
- if Center('Error in the program. In any case this program will now',True) then;
- if Center('Abort, all files will be closed and your data will be safe',True) then;
- if Center('The Error occurred in the following procedure: ',False) then;
- Case ErrCode of
- 1 : writeln('Adjust_Values');
- 2 : writeln('Define_Screen');
- end;
- if Center('Press Any key to continue',False) then;
- Ch := ReadKey;
- {$I-}
- Close(Data_File);
- Close(Screen_File);
- {$I+}
- If IOResult <> 0 then;
- CloseGraph;
- PopErase(MemWindo);
- Halt;
- end; { MemError }
-
- procedure GraphError(error_code : integer);
- begin
- CloseGraph;
- TextMode(3);
- window(20,10,60,15);
- TextBackground(Red);
- TextColor(White);
- ClrScr;
- Case error_code of
- -2 : begin
- writeln('Graphics Card not found .... ');
- writeln('Program is aborting .....');
- halt;
- end;
- -3 : begin
- writeln('Graphics Drivers Not Found!');
- writeln('Enter Name of Directory containing *.BGI files');
- readln(DriverPath);
- Window(1,1,80,25);
- Driver := Detect;
- Initgraph(Driver,Graph_Mode,DriverPath);
- end;
- -4 : begin
- writeln('Invalid Graphics Driver ...');
- writeln('Program is aborting ...');
- halt;
- end;
- -5 : begin
- writeln('Insufficient Memory to load Graphics driver');
- writeln('Program is aborting ...');
- halt;
- end;
- else
- begin
- writeln('Graphics error encountered! Error #',Error_Code);
- writeln('Program is aborting ...');
- halt;
- end;
- end; { case }
- end; { GraphError }
-
- procedure GenCursor;
- var
- Cursize : word;
- begin
- SetColor(GetMaxColor);
- line(0,0,0,Max_Y);
- Cursize := ImageSize(0,0,1,Max_Y);
- GetMem(VCursor, Cursize);
- GetImage(0,0,1,Max_Y,VCursor^);
- ClearViewPort;
- line(0,0,GetMaxX,0);
- Cursize := ImageSize(0,0,GetMaxX,1);
- GetMem(HCursor, Cursize);
- GetImage(0,0,GetMaxX,1,HCursor^);
- ClearViewPort;
- setColor(GetMaxColor-1);
- end; { GenCursor }
-
- procedure Evnt_Handler
- (Flags, cs, ip, ax, bx, cx, dx, si, di, ds, es, bp : word);
- { the above parameters are required by all interrupt type handlers }
- interrupt; { declare this an interrupt handler }
- begin
- Maus.event := ax;
- Maus.btnstatus := bx;
- Maus.horiz := cx;
- Maus.vert := dx;
- inline ( { exit any mouse handler as follows }
- $8b/$e5/ { Mov sp,bp }
- $5d/ { Pop bp }
- $07/ { Pop es }
- $1f/ { Pop ds }
- $5f/ { Pop di }
- $5e/ { Pop si }
- $5a/ { Pop dx }
- $59/ { Pop cx }
- $5b/ { Pop bx }
- $58/ { Pop ax }
- $cb ); { RETF }
- end; { Evnt_Handler }
-
- procedure Welcome_Screen;
- begin
- TextMode(3);
- PopShow(OpenWindo);
- Writeln;
- TextColor(Yellow);
- if Center('Welcome to JULIA SETS',True) THEN;
- if Center('Version 4.0',True) then;
- TextColor(LightCyan);
- writeln;
- writeln(' This Program is designed to let you explore the extraordinary world of the');
- writeln(' Mandelbrot and Julia sets. These sets of Complex numbers are defined as');
- writeln(' the set of numbers whose value never exceeds 2 when repeatedly subjected');
- writeln(' to the formula z = z',chr(253),' + c. The sets exist in the region ');
- writeln(' between -2 to 2 on the imaginary axis and -2 and 2 on the real axis of the');
- writeln(' Complex plane. The Complex Plane is described by a Imaginary number line ');
- writeln(' (the vertical or y axis) and a Real number line (the horizontal or x axis)');
- writeln(' In the program you will be asked to set the limits for the Real and ');
- writeln(' Imaginary axes, so values between -2 and 2 are expected for both. The Julia');
- writeln(' Set differs from the Mandelbrot set in that the value of c is specified by');
- writeln(' user. If a zero value is specified the program supplies c as the value of');
- writeln(' point being evaluated, this gives the Mandelbrot set. You must give the #');
- writeln(' of iterations to be used before the program gives up on a given point and');
- writeln(' calls it a member of a set. Reasonable values for large regions are in the');
- writeln(' 30-50 range, as you zoom in to smaller and smaller areas, you may increase ');
- writeln(' to 100-200 to get better resolution. If you don''t have a math coprocessor');
- writeln(' it will take a long time to do 30 iterations and almost forever to do > 100');
- writeln(' Good Luck and enjoy the show ');
- TextColor(Yellow);
- if Center('Press Any Key to Continue',False) then;
- ch := ReadKey;
- PopErase(OpenWindo);
- end; { Welcome_Screen }
-
-
- procedure Initialize;
-
- { this proc checks for the graphics screen and selects a mode based on
- a compromise between resolution and the number of colors. }
-
- var
- choice : char;
- x : integer;
-
- function UseMouse: boolean;
- var
- dummy : boolean;
- begin
- RestoreCrtMode;
- TextColor(LightCyan);
- UseMouse := False;
- PopShow(MouseWindo);
- ClrScr;
- Dummy := Center('You seem to have a mouse attached to your system. ',True);
- Dummy := Center('Some Mice do not work properly, if you have problems',True);
- Dummy := Center('try answering No to this Question ',True);
- Dummy := Center('Would you like to use your mouse? (Y/N) ',False);
- repeat
- Ch := ReadKey;
- until Ch in Yes_N_No;
- writeln(Ch);
- if Ch in Yes then UseMouse := True;
- PopErase(MouseWindo);
- SetGraphMode(Graph_Mode);
- end; { UseMouse }
-
- function GetMode(DriverStr : string): char;
- var
- ch : char;
- begin
- PopShow(GrafWindo);
- ClrScr;
- if Center('This is a graphics intensive program which uses colors to show',
- True) then; { true means line feed i.e. writeln }
- if Center('contrast between regions on the screen. Your '+DriverStr+' ',
- True) then; { false is like write }
- if Center('adapter in graphics mode can only display 4 colors at a time. ',
- True) then;
- if Center('You may choose which 4 colors below: ',
- True) then;
- if Center('(1) Black, Bright Green, Bright Red, Yellow [Default]',
- True) then;
- if Center('(2) Black, Bright Cyan, Bright Magenta, White ',
- True) then;
- if Center('(3) Black, Green, Red, Brown ',
- True) then;
- if Center('(4) Black, Cyan, Magenta, Light Gray ',
- True) then;
- if Center('Enter your choice (1-4) : ',
- False) then;
- Ch := ReadKey;
- writeln(Ch);
- GetMode := ch;
- PopErase(GrafWindo);
- end; { GetMode }
-
- function GetRes(DriverStr : string): char;
- var
- ch : char;
- begin
- PopShow(ResWindo);
- ClrScr;
- if Center('You have a '+DriverStr+' graphics adapter capable of 640 x 350',
- True) then; { true means line feed i.e. writeln }
- if Center('resolution. In order to increase speed this program normally ',
- True) then; { false is like write }
- if Center('only calculates values for half that resolution and plots 2 ',
- True) then;
- if Center('pixels. You may choose to have the higher resolution below at ',
- True) then;
- if Center('the sacrifice of calculation speed. ',
- True) then;
- if Center('(1) Low Resolution Mode (2 pixels per point) [Default]',
- True) then;
- if Center('(2) High Resolution Mode (1 pixel per point) (Slower) ',
- True) then;
- if Center('Enter your choice (1/2) : ',
- False) then;
- Ch := ReadKey;
- writeln(Ch);
- GetRes := ch;
- PopErase(ResWindo);
- end; { GetRes }
-
- begin
- TextMode(LastMode);
- TextColor(LightGreen);
- TextBackground(Black);
- DirectVideo := False;
- File_Name := '';
- Picture_Loaded := False;
- DetectGraph(Driver, Graph_Mode);
- X := GraphResult;
- if X <> 0 then GraphError(X);
- Case Driver of
- CGA,
- Reserved : begin
- Choice := GetMode('CGA');
- case choice of
- '2' : Graph_Mode := CGAC1;
- '3' : Graph_Mode := CGAC2;
- '4' : Graph_Mode := CGAC3;
- else Graph_Mode := CGAC0;
- end; { case }
- end;
- MCGA : begin
- Choice := GetMode('MCGA');
- case choice of
- '2' : Graph_Mode := MCGAC1;
- '3' : Graph_Mode := MCGAC2;
- '4' : Graph_Mode := MCGAC3;
- else Graph_Mode := MCGAC0;
- end; { case }
- end;
- EGA : begin
- Graph_Mode := EGAHi;
- Choice := GetRes('EGA');
- case choice of
- '2' : Resolution := EGAHighRes;
- else Resolution := EGALowRes;
- end; { case }
- end;
- EGA64 : begin
- Graph_Mode := EGA64Lo;
- Choice := GetRes('EGA');
- case choice of
- '2' : Resolution := EGAHighRes;
- else Resolution := EGALowRes;
- end; { case }
- end;
- VGA : begin
- Graph_Mode := VGAMed;
- Choice := GetRes('VGA');
- case choice of
- '2' : Resolution := EGAHighRes;
- else Resolution := EGALowRes;
- end; { case }
- end;
- ATT400 : begin
- Choice := GetMode('ATT400');
- case choice of
- '2' : Graph_Mode := ATT400C1;
- '3' : Graph_Mode := ATT400C2;
- '4' : Graph_Mode := ATT400C3;
- else Graph_Mode := ATT400C0;
- end; { case }
- end;
- PC3270 : Graph_Mode := PC3270Hi;
- HercMono : Graph_Mode := HercMonoHi;
- end;
- InitGraph(Driver,Graph_Mode,DriverPath);
- X := GraphResult;
- if X <> 0 then GraphError(X);
- case Driver of
- CGA, MCGA, Reserved,
- ATT400 : begin
- Color_Count := 54;
- Use_Color := Colors_4;
- Max_Colors := 3;
- Max_X := GetMaxX;
- XMul := 2;
- XDiv := 3;
- Resolution := CGAHighRes;
- end;
- EGA, VGA,
- EGA64 : begin
- Color_Count := 56;
- Use_Color := Colors_16;
- Max_Colors := 15;
- if Resolution = EGAHighRes then
- Max_X := GetMaxX
- else Max_X := GetMaxX div 2;
- end;
- else
- begin
- Color_Count := 56;
- Use_Color := Colors_2;
- Max_Colors := 1;
- Max_X := GetMaxX div 2;
- Resolution := EGALowRes;
- end;
- end; { case }
- SetUserCharSize(XMul,XDiv,YMul,YDiv);
- SetTextStyle(SmallFont,HorizDir,UserCharSize);
- Max_Y := GetMaxY - TextHeight('Low Real')-2;
- If Reset_Mse <> 0 then
- if UseMouse then
- Mouse_Flag := True;
- GenCursor;
- RestoreCrtMode;
- Scrn1 := Nil;
- Scrn2 := Nil;
- end; { Initialize }
-
- procedure ClrScrnMem;
- begin
- if Scrn1 <> nil then
- begin
- freemem(Scrn1,ScreenSize);
- freemem(Scrn2,ScreenSize);
- Scrn1 := Nil;
- Scrn2 := Nil;
- end;
- end; { ClrScrnMem }
-
- procedure Graphics_Cursor(ix,iy: integer);
- { Puts the graphics cursor at ix, iy, }
- { which are x and y expressed as integers. }
- var
- x, y : integer;
- begin
- MoveTo(ix,iy);
- putImage(ix,0,VCursor^,XORput);
- putImage(0,iy,HCursor^,XORput);
- end; { Graphics_Cursor }
-
- procedure Move_Cursor(var x, y : integer; FileRes : string);
- var
- ch : char;
- begin
- Stop := False;
- if Mouse_Flag then
- begin
- If Reset_Mse <> 0 then
- Set_Proc_Mse($0014,Seg(Evnt_Handler),Ofs(Evnt_Handler));
- Maus.Event := 0;
- if (FileRes = 'CGAHighRes') or (FileRes = 'EGALowRes') then
- Put_Mse(x * 2,y)
- else
- Put_Mse(x,y);
- Show_Mse;
- end
- else
- begin
- if (FileRes = 'EGALowRes') then
- x := x * 2;
- Graphics_Cursor(x, y);
- end;
- repeat
- if Mouse_Flag then
- if Maus.Event = 4 then
- begin
- x := Maus.Horiz;
- if (FileRes = 'CGAHighRes') then x := x div 2;
- y := Maus.Vert;
- Maus.Event := 0;
- Stop := True;
- Hide_Mse;
- end
- else
- if Maus.Event = $10 then
- begin
- x := 9999;
- Maus.Event := 0;
- Stop := True;
- Hide_Mse;
- end else
- else
- if KeyPressed then
- begin
- ch := ReadKey;
- case ch of
- #0 : begin
- ch := ReadKey;
- case ch of
- #72 : dec(y); { up arrow }
- #80 : inc(y); { down arrow }
- #75 : dec(x); { left arrow }
- #77 : inc(x); { right arrow }
- end; { case Inner }
- end; { #0 }
- '8' : dec(y,10); { shift up arrow }
- '4' : dec(x,10); { shift left arrow }
- '6' : inc(x,10); { shift right arrow }
- '2' : inc(y,10); { shift down arrow }
- #13 : Stop := True; { Return to enter point }
- #27 : begin { ESC to start process }
- x := 9999; { again }
- Stop := True;
- end;
- end; { Case Outer }
- if ((x < 0) or (x > Max_X)) and (Stop = False) then
- x := abs(-Max_X + abs(x));
- if (y < 0) or (y > Max_Y) then
- y := abs(-Max_Y + abs(y));
- Graphics_Cursor(GetX,GetY);
- Graphics_Cursor(x,y);
- end; { if keypressed }
- until stop;
- if (FileRes = 'EGALowRes') then
- x := x div 2;
- end; { Move_Cursor }
-
- procedure Plot(X, Y : integer; color : word);
- { this proc plots points on the screen. For high resolution width screens
- two adjacent pixels are set. }
-
- begin
- case Resolution of
- EGAHighRes,
- CGAHighRes : putpixel(X,Y,Color);
- else
- begin
- PutPixel(X*2,Y, Color);
- PutPixel(X*2+1,Y, Color);
- end;
- end; { case }
- end; { Plot }
-
- procedure Put_Limits;
- begin
- Str(Low.R:15:12,LowReal);
- Str(Low.I:15:12,LowImag);
- Str(High.R:15:12,HighReal);
- Str(High.I:15:12,HighImag);
- SetColor(GetMaxColor);
- SetTextJustify(LeftText,BottomText);
- SetUserCharSize(XMul,XDiv,YMul,YDiv);
- SetTextStyle(SmallFont,HorizDir,UserCharSize);
- LimitStr := 'Real: '+LowReal+' ~ '+HighReal+'; Imag: '+LowImag+' ~ '+
- HighImag;
- OutTextXY(0,GetMaxY-2,LimitStr);
- end;
-
- procedure Define_Screen;
- { this proc defines the area of the Julia set to be viewed.
- it can either be typed in at the keyboard, loaded as a partially
- completed screen, or as a smaller Sector of a completed picture }
-
- var
- IOError,
- x, y : integer;
- temp,
- ratio : double ;
- Complete : boolean;
- FileRes : String[10];
-
- procedure No_Blank(var RS : Real_String);
- { removes leading blanks from Real_Strings }
- var
- i : integer;
- begin
- i := 1;
- while RS[i] = ' ' do
- inc(i);
- Delete(RS,1,i-1);
- end; { No_Blank }
-
- procedure Adjust_Values;
- var
- temp, ratio : double;
- begin
- if Low.R > High.R then
- begin
- temp := Low.R;
- Low.R := High.R;
- High.R := temp;
- end;
- if Low.I > High.I then
- begin
- temp := Low.I;
- Low.I := High.I;
- High.I := temp;
- end;
- Sub_Comp(High,Low,Delta);
- Ratio := Abs(Delta.I / Delta.R);
- if Ratio >= Aspect then
- begin
- Dots_Horizontal := Round((Max_X + 1)*Aspect/Ratio)-1;
- Dots_Vertical := Max_Y;
- end
- else
- begin
- Dots_Vertical := Round((Max_Y + 1)*Ratio/Aspect)-1;
- Dots_Horizontal := Max_X;
- end;
- SetGraphMode(Graph_Mode);
- case Resolution of
- EGAHighRes,
- CGAHighRes : ScreenSize := ImageSize(0,0,Dots_Horizontal,Dots_Vertical div 2);
- else ScreenSize := ImageSize(0,0,Dots_Horizontal * 2, Dots_Vertical div 2);
- end; { case }
- if MaxAvail < 2 * ScreenSize then MemError(1);
- end; { Adjust_Values }
-
- procedure Sub_Picture;
- { allows the user to select a sub section of the completed screen to
- be enlarged, effectively zooming in on an area of interest }
- var
- ch : char;
- TempLow, TempHigh : Complex;
- x, y : integer;
- begin
- File_Name := '';
- x := Dots_horizontal div 2;
- y := Dots_Vertical div 2;
- Sub_Comp(High, Low, Delta);
- Move_Cursor(x, y, FileRes);
- if x > Max_X then
- begin
- Sub_Picture;
- Exit;
- end;
- if (FileRes = 'EGALowRes') and (Resolution = EGAHighRes) then
- plot(x*2, y, Max_Colors)
- else
- Plot(x, y, Max_Colors);
- { calculate new lower limits }
- TempLow.R := Low.R + (Delta.R * x / (Dots_Horizontal + 1));
- TempLow.I := High.I - (Delta.I * y / (Dots_Vertical + 1));
- Move_Cursor(x, y, FileRes);
- if x > Max_X then
- begin
- Sub_Picture;
- Exit;
- end;
- Plot(x, y, Max_Colors);
- High.R := Low.R + (Delta.R * x / (Dots_Horizontal + 1));
- High.I := High.I - (Delta.I * y / (Dots_Vertical + 1));
- Low := TempLow;
- Adjust_Values;
- with Screen_Data do
- begin
- Start_Y := 0;
- Dots_H := Dots_Horizontal;
- Dots_V := Dots_Vertical;
- Count := Max_Count;
- Str(Low.R, Low_Real);
- Str(Low.I, Low_Imag);
- Str(High.R, High_Real);
- Str(High.I, High_Imag);
- Str(Con.R, Con_Real);
- Str(Con.I, Con_Imag);
- No_Blank(Low_Imag);
- No_Blank(Low_Real);
- No_Blank(High_Imag);
- No_Blank(High_Real);
- ScrnSize := ScreenSize;
- ResStr := ResStrArray[Ord(Resolution)];
- end; { with }
- RestoreCrtMode;
- write('Maximum iteration count = ',Max_Count, '. Change it? (Y/N) ');
- repeat
- ch := readkey;
- until ch in Yes_N_No;
- writeln(ch);
- if ch in Yes then
- begin
- repeat
- write('Enter Maximum iteration count: ');
- {$I-}
- readln(Max_Count)
- {$I+}
- until IOResult = 0;
- if Max_Count < 10 then Max_Count := 10;
- Screen_Data.Count := Max_Count;
- end;
- writeln('Current Constant is : Real: ',Con.R:7:4,' Imaginary: ',Con.I:7:4);
- write('Change it (Y/N) : ');
- Repeat
- ch := readkey;
- until ch in Yes_N_No;
- writeln(ch);
- if ch in Yes then
- begin
- repeat
- write('Enter the real constant part : ');
- {$I-}
- Readln(Con.R);
- {$I+}
- until IOResult = 0;
- repeat
- write('Enter the imaginary constant part : ');
- {$I-}
- Readln(Con.I);
- {$I+}
- until IOResult = 0;
- end;
- write('Enter Note : ');
- Readln(Screen_Data.Note);
- SetGraphMode(Graph_Mode);
- end; { Sub_Picture }
-
- begin { Define_Screen }
- Complete := True;
- ch := 'N';
- if Picture_Loaded then
- begin
- write('Use Picture in Memory? (Y/N) ');
- repeat
- ch := readkey;
- until ch in Yes_N_No;
- writeln(ch);
- end;
- if ch in No then
- begin
- write('Load a picture file? (Y/N) ');
- repeat
- ch := readkey;
- until ch in Yes_N_No;
- writeln(ch);
- if ch in Yes then
- begin { load a picture file }
- repeat
- File_Name := Get_FileName('','Jul');
- if Pos('.',File_Name) <> 0 then
- Delete(File_Name,Pos('.',File_Name),4);
- Assign(Data_File, File_Name+'.Jul');
- {$I-}
- Reset(Data_File);
- {$I+}
- IOError := IOResult;
- if IOError = 0 then
- begin
- {$I-}
- Read(Data_File, Screen_Data);
- {$I+}
- IOError := IOResult;
- if IOError <> 0 then
- begin
- writeln('Old File Format Can Not Be read');
- Delay(2500);
- end;
- end;
- until IOError = 0;
- ClrScrnMem;
- ScreenSize := Screen_Data.ScrnSize;
- if MaxAvail < 2 * ScreenSize then MemError(2);
- GetMem(Scrn1,ScreenSize);
- GetMem(Scrn2,ScreenSize);
- Assign(Screen_File, File_Name+'.Scr');
- {$I-}
- Reset(Screen_File,ScreenSize);
- {$I+}
- If IOResult <> 0 then
- begin
- write('IO Error on opening Screen File');
- halt;
- end;
- BlockRead(Screen_File,Scrn1^,1,IOError);
- if IOError <> 1 then
- begin
- write('Error Reading Screen Image File');
- Close(Data_File);
- Close(Screen_File);
- Halt;
- end;
- BlockRead(Screen_File,Scrn2^,1,IOError);
- if IOError <> 1 then
- begin
- write('Error Reading Screen Image File');
- Close(Data_File);
- Close(Screen_File);
- Halt;
- end;
- Close(Data_File);
- Close(Screen_File);
- Picture_Loaded := True;
- end
- else
- begin
- repeat
- write('Enter range for the real (Horiz.) axis : ');
- {$I-}
- readln(Low.R, High.R);
- {$I+}
- until IOResult = 0;
- if Low.R > High.R then
- begin
- temp := Low.R;
- Low.R := High.R;
- High.R := temp;
- end;
- repeat
- write('Enter range for the imaginary (vert.) axis : ' );
- {$I-}
- readln(Low.I, High.I);
- {$I+}
- until IOResult = 0;
- if Low.I > High.I then
- begin
- temp := Low.I;
- Low.I := High.I;
- High.I := temp;
- end;
- repeat
- write('Enter maximum iteration count : ');
- {$I-}
- readln(Max_Count);
- {$I+}
- until IOResult = 0;
- if Max_Count < 10 then Max_Count := 10;
- repeat
- writeln('Enter the Values for the Constant to be added to the Equation Below');
- writeln('Zero gives the MandelBrot Set. Enter the real part and the imaginary');
- write('part separated by a space (i.e. 0 0) : ');
- {$I-}
- Readln(Con.R, Con.I);
- {$I+}
- until IOResult = 0;
- write('Enter Note : ');
- Readln(Screen_Data.Note);
- Start_Y := 0;
- Adjust_Values;
- with Screen_Data do
- begin
- Dots_H := Dots_Horizontal;
- Dots_V := Dots_Vertical;
- Count := Max_Count;
- Str(Low.R, Low_Real);
- Str(Low.I, Low_Imag);
- Str(High.R, High_Real);
- Str(High.I, High_Imag);
- Str(Con.R, Con_Real);
- Str(Con.I, Con_Imag);
- No_Blank(Low_Imag);
- No_Blank(Low_Real);
- No_Blank(High_Imag);
- No_Blank(High_Real);
- ScrnSize := ScreenSize;
- ResStr := ResStrArray[Ord(Resolution)];
- end; { with }
- Picture_Loaded := False;
- File_Name := '';
- end { else }
- end; { if ch in No then }
- if Picture_Loaded then
- begin { dump picture to screen }
- with Screen_Data do
- begin
- Start_Y := Start;
- Max_Count := Count ;
- Dots_Vertical := Dots_V;
- Dots_Horizontal := Dots_H;
- Val(Low_Real,Low.R,X);
- Val(Low_Imag,Low.I,X);
- Val(High_Real,High.R,X);
- Val(High_Imag,High.I,X);
- Val(Con_Real,Con.R,X);
- Val(Con_Imag,Con.I,X);
- FileRes := ResStr;
- end;
- if Start_Y <= Dots_Vertical then
- begin
- write('Picture File is Incomplete, Do you want to complete the picture (Y/N) ');
- repeat
- ch := readkey;
- until ch in Yes_N_No;
- writeln(ch);
- if ch in Yes then Complete := False
- else Complete := True;
- end;
- SetGraphMode(Graph_Mode);
- PutImage(0,0,Scrn1^,NormalPut);
- PutImage(0,Dots_Vertical div 2 + 1,Scrn2^,NormalPut);
- ClrScrnMem;
- if Complete then
- begin
- Put_Limits;
- Sub_Picture;
- end
- else
- Sub_Comp(High,Low,Delta);
- end;
- Delta.R := Delta.R / (Dots_Horizontal + 1);
- Delta.I := Delta.I / (Dots_Vertical + 1 );
- end; { Define_screen }
-
- procedure Generate;
- { generates the screen display. The section marked 1* is where code has been
- optimized by putting the complex number math instructions in this procedure
- rather than calling the procedures in the Cmplx unit }
- var
- Done : boolean;
- x, y, PointColor, Count : integer;
- Z_Point, C_Point: Complex;
- Temp : Double;
- Constant : ^Complex;
-
- begin
- Done := False;
- Put_Limits;
- Plot(Dots_Horizontal, Dots_Vertical, Max_Colors);
- C_Point.I := High.I - Start_Y * Delta.I;
- Y := Start_Y;
- if (Con.R = 0) and (Con.I = 0) then
- Constant := @C_Point
- else
- Constant := @Con;
- while (Y <= Dots_Vertical) and NOT KeyPressed do
- begin
- C_Point.R := Low.R - Delta.R;
- for x := 0 to Dots_Horizontal do
- begin
- Plot(x, y, Max_Colors);
- C_Point.R := C_Point.R + Delta.R;
- Z_Point := C_Point;
- Count := 0;
- while (Count <= Max_Count) and (Square_Size_Of_C(Z_Point) < 4.0) do
- begin
- Temp := Sqr(Z_point.R) - Sqr(Z_Point.I) ;
- Z_Point.I := 2.0 * Z_Point.I * Z_Point.R + Constant^.I;
- Z_Point.R := Temp + Constant^.R;
- Count := Succ(Count);
- end;
- if Count < Max_Count then
- PointColor := Use_Color[Count mod Color_Count]
- else PointColor := 0;
- Plot(x,y,PointColor);
- end;
- C_Point.I := C_Point.I - Delta.I;
- Y := Y + 1;
- end; { while }
- Screen_Data.Start := Y;
- ClrScrnMem; { Free up Previous Screen Image Mem }
- GetMem(Scrn1,ScreenSize); { get memory needed to hold screen }
- GetMem(Scrn2,ScreenSize); { images }
- case Resolution of { depending on the Screen Res we must }
- EGAHighRes, { define the region for capture and }
- CGAHighRes : begin { capture the screen images }
- GetImage(0,0,Dots_Horizontal,Dots_Vertical div 2,Scrn1^);
- GetImage(0,Dots_Vertical div 2 + 1,
- Dots_Horizontal,Dots_Vertical,Scrn2^);
- end;
- else begin
- GetImage(0,0,Dots_Horizontal * 2, Dots_Vertical div 2,Scrn1^);
- GetImage(0,Dots_Vertical div 2 + 1,
- Dots_Horizontal * 2,Dots_Vertical,Scrn2^);
- end;
- end; { case }
- end; { Generate }
-
- procedure Wrap_Up;
- { deals with the shutting down of a picture }
- var
- x : integer;
- begin
- Picture_Loaded := True;
- if KeyPressed then Sound(440)
- else
- begin
- Sound(660);
- Delay(20);
- Sound(1000);
- end;
- Delay(50);
- NoSound;
- ch := ReadKey;
- RestoreCrtMode;
- Write('Save Picture? (Y/N) ');
- repeat
- ch := readkey;
- until ch in Yes_N_No;
- writeln(ch);
- if ch in Yes then
- begin
- if File_Name <> '' then
- begin
- write('Save as ',File_Name,'? (Y/N) ' );
- repeat
- ch := readkey;
- until ch in Yes_N_No;
- writeln(ch);
- end
- else ch := 'N';
- if ch in No then
- File_Name := Get_FileName('','Jul');
- if Pos('.',File_Name) <> 0 then
- Delete(File_Name,Pos('.',File_Name),4);
- Assign(Screen_File,File_Name+'.Scr');
- Rewrite(Screen_File,ScreenSize);
- Assign(Data_File,File_Name+'.JUL');
- Rewrite(Data_File);
- Write(Data_File,Screen_Data);
- BlockWrite(Screen_File,Scrn1^,1,IOError);
- BlockWrite(Screen_File,Scrn2^,1,IOError);
- Close(Data_File);
- Close(Screen_File);
- end; { then }
- write(' Do Another ? (Y/N)');
- repeat
- ch := readkey;
- until ch in Yes_N_No;
- writeln(ch);
- end; { Wrap_Up }
-
- BEGIN { Main }
- Welcome_Screen;
- Initialize;
- repeat
- Define_Screen;
- Generate;
- Wrap_Up;
- until ch in No;
- RestoreCrtMode;
- END.
-